この記事では実際に XPages アプリケーションでメモリリークを起こさせて、それが MAT でどのように発見できるかを見てみます。試した環境は以下になります。
Eclipse Memory Analyzer Tool は Eclipse IDE のプラグインとしても、単体の RCP プログラムとしても公開されています。
ここでは Eclipse IDE の上にプラグインとして構成し、さらに IBM Diagnostic Tool Framework for Java を追加でインストールする方法を紹介します。
現在リリースされている Eclipse IDE にはすでに 4.2 ですが、IBM Diagnostic Tool Framework for Java Version 1.10 のページで Eclipse 3.4 をベースにした記載があるため、筆者は Eclipse Ganymede SR2 (3.4.2) のダウンロードサイトより Eclipse IDE for Java EE Developer をダウンロードして使用しました。
展開した Eclipse IDE を開き、メニューから「Help」→「Software Updates」を選択し、「Available Software」タブを選択します。「Add Site」ボタンでダイアログを開き、Eclipse Memory Analyser Tool (http://www.eclipse.org/mat) の Memory Analyzer 1.2.1 Release のダウンロードページにある アップデートサイトの URL (http://download.eclipse.org/mat/1.2/update-site/)を指定して MAT のプラグインをインストールします。
サンプルとして使用するのは以下のような XPage アプリケーションです。このアプリションでは入力フィールドに設定されたサイズの配列のデータを作成しスコープ変数の applicationScope 変数に値を設定します。アプリケーションスコープの変数は、XPages アプリケーションとしてデータを保持するので、大きな値を設定することでメモリを圧迫させることができます。この記事での動作確認では入力フィールドに「500」を設定し、500MB のデータを生成しました。
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:label value="Leak data size: " id="label1"></xp:label>
<xp:inputText id="inputRepeatCount" required="true">
<xp:this.converter>
<xp:convertNumber type="number"></xp:convertNumber>
</xp:this.converter>
<xp:this.validators>
<xp:validateRequired message="Data size is mandatory,"></xp:validateRequired>
<xp:validateLongRange minimum="1" maximum="1000"></xp:validateLongRange>
</xp:this.validators>
</xp:inputText>
<xp:label value="MB" id="label2"></xp:label>
<xp:button value="Generate Memory Leak" id="buttonGenMemLeak">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="panelMessage">
<xp:this.action><![CDATA[#{javascript:
var repeat = getComponent("inputRepeatCount").getValue();
print ("Generating memory leak with " + repeat + " MB.");
var testdata_16 = "0123456789ABCDEF";
var testdata_1024 = "";
for (i=0; i<64; i++) {
testdata_1024 = testdata_1024 + testdata_16;
}
var listsize = 1024 * repeat;
var list = new Array(listsize);
for (j=0; j< listsize; j++) {
list[j] = testdata_1024;
}
applicationScope.testdatalist = list;
viewScope.message = list.length + "x1024 bytes data was stored in applicationScope.";
}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
 
<xp:button value="Clear Memory Leak" id="buttonClearMemLeak">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" disableValidators="true" refreshId="panelMessage">
<xp:this.action><![CDATA[#{javascript:
applicationScope.testdatalist = null;
viewScope.message = "ApplicationScope data is cleared.";
}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:br></xp:br>
<xp:panel id="panelMessage">
<xp:text escape="true" id="computedField1" value="#{viewScope.message}"></xp:text>
</xp:panel>
</xp:view>